package com.TheyChat.service.socket;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.TheyChat.service.interfaces.entity.SocketNoServerUser;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint("/TheyChat/NoneUser/{peerId}")
public class NoneUserSocketServer {

    private static final Map<String, Session> peerIdSessionMap = new ConcurrentHashMap<>();
    private static final Map<String, SocketNoServerUser> peerUserSessionMap = new ConcurrentHashMap<>();

    //    private static final Map<String, Session> peerNickNameSessionMap = new ConcurrentHashMap<>();
    @OnOpen
//    @RequestMapping("/{peerId}/{nickname}")
    public void onOpen(Session session, @PathParam("peerId") String peerId) {
        log.info("user:,on open:the session is is :{},the peer id is:{}",  session.getId(), peerId);
        Session removedSession = NoneUserSocketServer.peerIdSessionMap.remove(peerId);


        try {
            if (Objects.nonNull(removedSession)) {
                removedSession.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            NoneUserSocketServer.peerIdSessionMap.put(peerId, session);

            SocketNoServerUser userSession = new SocketNoServerUser();
            userSession.setSession(session);
            Map<String, List<String>> params=session.getRequestParameterMap();
            List<String> nickname = params.get("nickname");
            userSession.setNickname(nickname.get(0));
            userSession.setPeerId(peerId);
            NoneUserSocketServer.peerUserSessionMap.put(peerId, userSession);
            System.out.println(userSession);
            refreshOnlineSessionsList();
        }
    }

    @OnClose
//    @RequestMapping("/{peerId}")
    public void onClose(Session session, @PathParam("peerId") String peerId) {
        log.warn("on close:the session is is :{},the peer id is:{}", session.getId(), peerId);

        Session removedSession = NoneUserSocketServer.peerIdSessionMap.remove(peerId);
        try {
            if (Objects.nonNull(removedSession)) {
                removedSession.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            refreshOnlineSessionsList();
        }
    }

    @OnError
//    @RequestMapping("/{peerId}")
    public void onError(Session session, Throwable e, @PathParam("peerId") String peerId) {
        log.error("on error:the session is is :{},the exception class is: {},the peer id is:{}", session.getId(), e.getClass(), peerId);
        onClose(session, peerId);

        e.printStackTrace();
    }

    private void refreshOnlineSessionsList() {
//        NoneUserSocketServer.peerIdSessionMap.forEach((key, value) -> {
//            value.getAsyncRemote().sendText(JSON.toJSONString(NoneUserSocketServer.peerUserSessionMap.keySet().toString()));
//        });
        NoneUserSocketServer.peerIdSessionMap.forEach((key, value) -> {
            value.getAsyncRemote().sendText(JSON.toJSONString(NoneUserSocketServer.peerIdSessionMap.keySet()));
        });

    }

    @OnMessage
    public void onMessage(String message, Session session){
        System.out.println(JSONObject.parse(message));
    }
}
